Skip to content

feat: Airtable-style ListView grid view optimization - #594

Merged
hotlong merged 4 commits into
mainfrom
copilot/optimize-listview-ui
Feb 18, 2026
Merged

feat: Airtable-style ListView grid view optimization#594
hotlong merged 4 commits into
mainfrom
copilot/optimize-listview-ui

Conversation

Copilot AI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

Closes the visual/interaction gap between ObjectUI's grid view and Airtable's list view across ListView, ObjectGrid, and data-table.

P0 — Visual alignment

  • Record count status barListView bottom bar shows {n} records when data is loaded
  • "+ Add record" row — New showAddRow/onAddRecord props on DataTableSchema; ObjectGrid auto-enables when operations.create is truthy
  • Compound cellsListColumn.prefix config renders a badge/text prefix inline with the primary cell value:
    { field: 'customer_name', label: 'Customer', prefix: { field: 'category', type: 'badge' } }
  • DateTime split displayDateTimeCellRenderer renders date and time as visually separated spans (2/18/2026 + muted 12:57 am); new datetime auto-inference for *_at/*_time field patterns
  • Row style refinementbg-background border-b border-border/50 hover:bg-muted/30 on data rows for clean Airtable-like appearance

P1 — Polish

  • Inline sort arrows — Reduced to h-3, hidden until column hover, text-primary when active sort
  • Column header type icons — ObjectGrid passes headerIcon per column mapped from inferred type (Type/Hash/Calendar/Clock/CheckSquare/User/Tag)

Type changes

  • DataTableSchema: added showAddRow, onAddRecord
  • ListColumnSchema (Zod): added optional prefix: { field, type? } for compound cell config
  • ObjectGridProps: added onAddRecord callback

Tests

11 new tests covering record count bar, add record row, compound cells, datetime inference, column type icons, and DateTimeCellRenderer edge cases. 369 tests pass across 28 related test files.

Original prompt

This section details on the original issue you should resolve

<issue_title>参考 Airtable 优化 ListView 列表视图(Grid View)</issue_title>
<issue_description>##
参考 Airtable 客户列表页面,对 ObjectUI 的 ListView + ObjectGrid + data-table 进行全面优化,使其在视觉和交互上达到 Airtable 同等水平。

Airtable 参考截图


📊 当前现状分析

✅ 已实现功能

功能 状态 位置
Airtable 风格工具栏 (Hide/Filter/Group/Sort/Color/Search) packages/plugin-list/src/ListView.tsx L634-888
FilterBuilder (Popover) ListView.tsx L694-729
SortBuilder (Popover) ListView.tsx L742-777
Hide Fields ListView.tsx L638-692
Search (可展开) ListView.tsx L850-887
Quick Filters (标签) ListView.tsx L894-917
Density / Row Height ListView.tsx L790-800
Export (CSV/JSON) ListView.tsx L802-832
列宽调整 data-table.tsx
列顺序拖拽 data-table.tsx
行选择 data-table.tsx
行号显示 ObjectGrid.tsx L745
冻结列 ObjectGrid.tsx L747
分组数据 ObjectGrid.tsx L978-998
自动类型推断 (日期/状态/金额等) ObjectGrid.tsx L346-388
Badge 单元格渲染 ObjectGrid.tsx L370-379

🔴 Gap 分析:与 Airtable 的差距

P0 — 必须实现(视觉对齐)

1. 记录数量底栏 📊

现状:无记录计数显示
Airtable:底部显示 15 records,选中时显示选中数量

  • packages/plugin-list/src/ListView.tsx
  • 方案:在 ListView 底部添加状态栏,显示 {data.length} records
  • 选中行时切换显示 {selectedCount} of {total} selected
  • 工作量:S (2-4h)
2. "+ Add record" 添加行 ➕

现状:无底部添加行入口
Airtable:表格最底行有 + Add record 可点击

  • packages/plugin-grid/src/ObjectGrid.tsx + packages/components/src/renderers/complex/data-table.tsx
  • 方案data-table 新增 showAddRow prop,当 operations.create 启用时渲染
  • 点击触发 onAddRecord 回调或打开 NavigationOverlay 的创建表单
  • 工作量:M (4-8h)
3. 首列复合单元格(Badge + 文本)🏷️

现状:Badge 字段和 Name 字段分别在各自列中独立渲染
Airtable:第一列同一个单元格内 [Enterprise Badge] Acme Corp

  • packages/types/src/views.ts (ListColumn 类型) + packages/plugin-grid/src/ObjectGrid.tsx
  • 方案ListColumn 新增 prefix 配置:
    { field: 'customer_name', label: 'Customer Name', prefix: { field: 'category', type: 'badge' } }
    generateColumns() 中检测 prefix 配置并合成 compound cell renderer
  • 工作量:M (4-8h)
4. 日期时间分离显示 🕐

现状:日期字段使用 formatDate() 统一格式化
AirtableCreated Time 列显示 2/18/2026 12:57am(日期和时间视觉分离)

  • packages/fields/src/ (新增 datetime cell renderer)
  • 方案:新增 datetime 类型的 cell renderer:
    <span>{date}</span>
    <span className="text-muted-foreground ml-2">{time}</span>
    ObjectGrid.inferColumnType() 中添加 created_time/created_at 等模式匹配
  • 工作量:S (2-4h)
5. 行样式精细化 🎨

现状:可能有条纹背景(zebra striping),hover 效果较重
Airtable:纯白背景 + 细 border-b 分隔 + 极轻 hover

  • packages/components/src/renderers/complex/data-table.tsx
  • 方案
    • 移除 zebra striping(如有),确保所有行纯白背景
    • hover:bg-muted/30 替换为更轻的 hover
    • 确保 border-b border-border/50 分隔线
  • 工作量:S (1-2h)

P1 — 锦上添花

6. 排序箭头内联到列标题 ⬆️

现状:使用 ChevronsUpDown 图标按钮
Airtable:标题文本后直接跟随小 /

  • packages/components/src/renderers/complex/data-table.tsx
  • 工作量:S (2h)
7. 列标题类型图标 🔤

现状:列标题只有文本
Airtable:列标题前显示字段类型图标(如 Aᵢ = 文本, # = 数字, 📅 = 日期)

  • packages/plugin-grid/src/ObjectGrid.tsx
  • 工作量:M (4h)
8. 侧边栏视图导航 📋

现状:视图切换在工具栏顶部
Airtable:左侧边栏列出"客户互动日历"、"客户列表页面"等视图

  • packages/plugin-list/src/ListView.tsx
  • 工作量:L (1-2d)

🔗 涉及文件

文件路径 改动范围
packages/plugin-list/src/ListView.tsx 底栏、侧边栏
packages/plugin-grid/src/ObjectGrid.tsx 复合单元格、类型图标
packages/components/src/renderers/complex/data-table.tsx 行样式、排序箭头、添加行
packages/types/src/views.ts ListColumn prefix 类型
packages/fields/src/ datetime 渲染器
packages/plugin-list/src/__tests__/ListView.test.tsx 新功能测试
packages/plugin-grid/src/__tests__/ ObjectGrid 测试
packages/components/src/renderers/complex/__tests__/ data-table 测试
packages/components/src/stories-json/list-view.stories.tsx Storybook 示例

✅ 完成标准

  • P0-1: 记录数量底栏 — {n} records 显示正常
  • P0-2: "+ Add record" 行 — 可点击触发创建流程
  • P0-3: 首列复合单元格 — Badge + 文本在同一列渲染
  • P0-4: 日期时间分离显示 — 日期和时间视觉区分
  • P0-5: 行样式精细化 — 纯白行 + 细分隔线 + 轻 hover
  • P1-6: 排序箭头内联
  • P1-7: 列标题类型图标
  • P1-8: 侧边栏视图导航
  • 所有新增功能有对应单元测试
  • Storybook 示例更新
  • pnpm test 全部通过
  • 更新 ROADMAP.md 相关条目

  • 类型:增强 Enhancement
  • 标签:enhancement
  • 完成后需运行 test & 更新 roadmap</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@vercel

vercel Bot commented Feb 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
objectui Error Error Feb 18, 2026 9:00am
objectui-demo Error Error Feb 18, 2026 9:00am
objectui-storybook Error Error Feb 18, 2026 9:00am

Request Review

- P0-1: Record count status bar at bottom of ListView
- P0-2: "+ Add record" row in data-table (showAddRow prop)
- P0-3: Compound cells with prefix badge configuration
- P0-4: DateTime split display (date + muted time)
- P0-5: Row style refinement (white bg, fine borders, light hover)
- P1-6: Inline sort arrows (smaller, appears on hover)
- P1-7: Column header type icons (text/number/date/boolean/user/select)

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI and others added 2 commits February 18, 2026 08:54
…tGrid, and DateTimeCellRenderer

- ListView: record count bar visibility tests with data/no-data scenarios
- DataTable: type-level test for showAddRow and onAddRecord schema properties
- ObjectGrid: column header type icons, datetime inference, compound cell
  prefix badge, and add record row tests
- DateTimeCellRenderer: split date/time rendering, null value, invalid date

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add ListView record count bar tests
- Add data-table showAddRow/onAddRecord schema tests
- Add ObjectGrid datetime inference, compound cell, type icons, add record tests
- Add DateTimeCellRenderer unit tests
- Update ROADMAP.md with new Airtable feature entries

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI changed the title [WIP] Optimize ListView component for better visual and interactive experience feat: Airtable-style ListView grid view optimization Feb 18, 2026
Copilot AI requested a review from hotlong February 18, 2026 09:03
@hotlong
hotlong marked this pull request as ready for review February 18, 2026 09:14
Copilot AI review requested due to automatic review settings February 18, 2026 09:14
@hotlong
hotlong merged commit c4e18e3 into main Feb 18, 2026
3 of 6 checks passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements comprehensive Airtable-style visual and interaction improvements to the ListView grid view, bridging the gap between ObjectUI's data tables and Airtable's polished list view experience. The changes span across ListView, ObjectGrid, and data-table components to deliver a cohesive, production-ready grid interface.

Changes:

  • Record count status bar — Shows {n} records at the bottom of ListView when data is loaded, with proper singular/plural handling
  • "+ Add record" row — New showAddRow/onAddRecord props enable Airtable-style bottom row for creating records; ObjectGrid auto-enables when operations.create is truthy
  • Compound cells with prefix badges — New ListColumn.prefix config (e.g., { field: 'category', type: 'badge' }) renders badge/text inline before main cell value
  • DateTime split display — Refactored DateTimeCellRenderer to visually separate date (2/18/2026) and time (12:57 am in muted text); auto-inferred for *_at/*_time field patterns
  • Row styling refinement — Applied clean Airtable-style row appearance: bg-background border-b border-border/50 hover:bg-muted/30
  • Inline sort arrows — Reduced to h-3, hidden until column hover (opacity-0 group-hover:opacity-50), colored text-primary when active
  • Column header type icons — ObjectGrid automatically adds type-appropriate icons (Type/Hash/Calendar/Clock/CheckSquare/User/Tag) to column headers via headerIcon prop

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/types/src/zod/objectql.zod.ts Added prefix property to ListColumnSchema for compound cell configuration
packages/types/src/data-display.ts Added showAddRow and onAddRecord properties to DataTableSchema
packages/plugin-list/src/ListView.tsx Implemented record count status bar at bottom, shown when data is loaded
packages/plugin-grid/src/ObjectGrid.tsx Added column type icon mapping, datetime inference patterns, compound cell prefix rendering, and auto-enable add record row when operations.create is truthy
packages/fields/src/index.tsx Refactored DateTimeCellRenderer to split date/time display with muted styling for time component
packages/components/src/renderers/complex/data-table.tsx Implemented add record row, refined row styling, reduced sort arrow size with hover/active states, added headerIcon support in column headers
packages/plugin-list/src/__tests__/ListView.test.tsx Added tests for record count bar visibility logic
packages/plugin-grid/src/__tests__/airtable-style.test.tsx Added 9 tests covering datetime inference, column type icons, compound cells, and add record row
packages/fields/src/__tests__/datetime-cell.test.tsx New test file with 3 tests for DateTimeCellRenderer edge cases
packages/components/src/renderers/complex/__tests__/data-table.test.ts Added test verifying showAddRow/onAddRecord schema properties
ROADMAP.md Marked 7 Airtable-style features as complete in P6.1 ObjectGrid section

Comment on lines +76 to +79
prefix: z.object({
field: z.string().describe('Field name to render as prefix'),
type: z.enum(['badge', 'text']).optional().describe('Renderer type for the prefix'),
}).optional().describe('Prefix configuration for compound cell rendering (Airtable-style)'),

Copilot AI Feb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment states "Mirrors @objectstack/spec/ui ListColumnSchema" but the new prefix property appears to be an ObjectUI-specific extension not in the upstream spec. Consider either: (1) verifying this property exists in the latest @objectstack/spec and updating the comment if needed, or (2) adding a note that clarifies this is an ObjectUI-specific extension (similar to how other parts of the codebase mark extensions with "NOTE: This is ObjectUI-specific and not part of @objectstack/spec").

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

参考 Airtable 优化 ListView 列表视图(Grid View)

3 participants